API Corner

Installing Fonts

by Alyce Watson

Home

Tips For the Hobbyist

Nally's Applications

Measuring an Angle

Maphandle Listboxes

About GUIs

Convert Old Code

Installing Fonts

Tip Corner

Stopwatch for LB4

Run with Params

Newsletter help

Index


Fonts in Liberty BASIC

A font is a typeface used to display text.

Liberty BASIC gives you the ability to specify fonts for windows, controls and graphics. For information on using fonts in Liberty BASIC, see the helpfile on "How to Specify Fonts" and read newsletter issue #68.

The Liberty BASIC font command requires that you know the font face name. This is not necessarily the same as the filename of the font. For example, a font called "Words of Love" has a filename, "wordsoflove.ttf". You refer to it in LB font commands as "words_of_love". It is important to understand the distinction between the face name, the filename and the Liberty BASIC name. The Liberty BASIC name is identical to the face name, but any blank spaces are replaced by an underscore character.

You can count on users having these Windows fonts installed:

If your program requires fonts other than the ones on the "safe list" it is best to include the font file in the distribution of the program. You install the font by filename, but you refer to it in LB by face name. There are two easy ways to determine the facename of a font file. The easiest way is to make note of it from the font source. Some websites that provide fonts are listed later in this article. Another easy way to find the face name is to view the font in the Windows/fonts directory. Click on the filename and the Windows font viewer is activated to give you all the information you need about the font.

Installing Fonts

Fonts must be properly installed before they can be used in a program. You could ask your users to install the fonts using the Windows font installer, but that isn't the most professional way to handle it!

Installing fonts is as easy as moving the font file to the user's font folder. This is usually "windows\fonts." It is necessary to retrieve the correct folder name and path, however. You cannot be absolutely sure that users have Windows installed on their 'C' drive and that their system configuration is identical to yours. The Windows Shell32 API provides a function to retrieve the location of the "fonts" folder, called SHGetSpecialFolderLocation . The function has an argument whose value tells it which special folder location to retrieve. The flag for the fonts folder has a value of '20'.

This API call is a bit more complicated than most. It requires a struct to receive the information you request in the call.

struct IDL,cb As Long, abID As short

The struct is passed into the API call:

    
    CSIDL.FONTS = 20
    calldll #shell32, "SHGetSpecialFolderLocation",_
        0 as long, CSIDL.FONTS as long, IDL as struct,_
        ret as long

It is usually possible to read the returned data from the struct in API functions requiring structs. It is necessary to read the information from the struct, but in this case, it returns a pointer which must then be used in another API call to retrieve the contents of the string. To retrieve the pointer to the needed path information:

id=IDL.cb.struct

The API function that retrieves the actual path name to the fonts folder is SHGetPathFromIDListA. First, create a string variable large enough to contain the path information. The function takes the pointer and returns the path information in the string variable. The path name is followed by a null character, which is chr$(0). Chop the path name at the null character with the LEFT$() function, as follows:

    'Create a buffer
    Path$ = Space$(512)+chr$(0)

    calldll #shell32, "SHGetPathFromIDListA",_
    id as long, Path$ as ptr, ret as long

    'Remove the null chars
    Path$ = Left$(Path$, InStr(Path$, Chr$(0)) - 1)

You must know the location of the fontfile so that you can move it to the Windows "fonts" folder. If the fontfile is in the same directory as your program, you can use DefaultDir$ + "\myfont.ttf" (with the proper filename, of course) as the source filename for the moving operation. The destination filename is the font folder path you retrieved, plus a backslash, plus the filename of the font.

Path$ + "\" + "fontname.ttf"

Windows Kernel32 provides an easy way to move a file from one location to another. It looks like this, with a return of 0 if the call is successful:

    calldll #kernel32, "MoveFileA",_
    lpExistingFileName$ as ptr,_
    lpNewFileName$ as ptr,_
    result as long    'nonzero if success

Of course, your program only installs the font the first time it is run. Using this method, the font file is moved from its original location, such as your program's DefaultDir$ to the Windows font folder.

Fonts Online

Here are some online sources for free and commercial fonts. A web search will quickly turn up more sites, but these are a start.

DEMO

Download a font file, or obtain one from some other source, and place it in a folder somewhere on your system. Use the filedialog to navigate to the font file in the demo below and the font will be installed on your system.

'Please note that the filename is not necessarily
'the same as the FACE NAME. For instance,
'wordsoflove.ttf is the file name for the font
'words_of_love. You'll need the face name to
'specify fonts in LB.
'
'
filedialog "Open", "*.fnt;*.ttf",font$
if font$="" then end

print "font chosen is ";font$

CSIDL.FONTS = 20
fontDir$ = GetSpecialfolder$(CSIDL.FONTS)

print "font directory is ";fontDir$

if fontDir$<>"Error" then
    fontname$=SeparateFile$(font$)
    re = MoveFile(font$, fontDir$ + "\" + fontname$)
    if re then
        print "Font installed successfully"
    else
        print "Unable to install font."
    end if
end if
wait
end

Function GetSpecialfolder$(CSIDL)
    struct IDL,cb As Long, abID As short
    'Get the special folder
    calldll #shell32, "SHGetSpecialFolderLocation",_
        0 as long, CSIDL as long, IDL as struct,_
        ret as long

    if ret=0 then
    'Create a buffer
    Path$ = Space$(512)+chr$(0)
    'Get the path from the IDList
    id=IDL.cb.struct

    calldll #shell32, "SHGetPathFromIDListA",_
    id as long, Path$ as ptr, ret as long

    'Remove the null chars
    GetSpecialfolder$ = Left$(Path$, InStr(Path$, Chr$(0)) - 1)

    else
    GetSpecialfolder$ = "Error"
    end if
End Function

Function MoveFile(lpExistingFileName$,lpNewFileName$)
    calldll #kernel32, "MoveFileA",_
    lpExistingFileName$ as ptr,_
    lpNewFileName$ as ptr,_
    MoveFile as long    'nonzero if success
    End Function

Function SeparateFile$(f$)
    fileindex=Len(f$)
    filelength=Len(f$)
      While Mid$(f$, fileindex,1)<>"\"
        fileindex=fileindex-1
      Wend
    SeparateFile$=Right$(f$,filelength-fileindex)
End Function


Home

Tips For the Hobbyist

Nally's Applications

Measuring an Angle

Maphandle Listboxes

About GUIs

Convert Old Code

Installing Fonts

Tip Corner

Stopwatch for LB4

Run with Params

Newsletter help

Index